home *** CD-ROM | disk | FTP | other *** search
/ Programming Languages Suite / ProgramD2.iso / Borland / Borland C++ V5.02 / COLMNHDR.PAK / COLMNHDX.CPP < prev    next >
C/C++ Source or Header  |  1997-05-06  |  10KB  |  375 lines

  1. //----------------------------------------------------------------------------
  2. // ObjectWindows
  3. // Copyright (c) 1995, 1996 by Borland International, All Rights Reserved
  4. //
  5. // Illustrates usage of TColumnHeader class
  6. //----------------------------------------------------------------------------
  7. #include <owl/pch.h>
  8. #if !defined(OWL_LISTBOX_H)
  9. # include <owl/listbox.h>
  10. #endif
  11. #if !defined(OWL_COLMNHDR_H)
  12. # include <owl/colmnhdr.h>
  13. #endif
  14. #if !defined(OWL_INPUTDIA_H)
  15. # include <owl/inputdia.h>
  16. #endif
  17. #if !defined(OWL_VALIDATE_H)
  18. # include <owl/validate.h>
  19. #endif
  20. #if !defined(OWL_GDIOBJEC_H)
  21. # include <owl/gdiobjec.h>
  22. #endif
  23. #if !defined(OWL_CHOOSEFO_H)
  24. # include <owl/choosefo.h>
  25. #endif
  26. #include "colmnhdr.h"
  27.  
  28. //
  29. // A few constants
  30. //
  31. const int   UnChk = TCommandEnabler::Unchecked;
  32. const int   Chk   = TCommandEnabler::Checked;
  33. const int   ColHdrID  = 0x100;              // ID of ColumnHeader control
  34. const int   ListID    = 0x200;              // ID of ListBox control
  35.  
  36. //
  37. // Class TSampleApp
  38. // ~~~~~ ~~~~~~~~~~
  39. class TSampleApp : public TApplication {
  40.   public:
  41.     void    InitMainWindow();
  42. };
  43.  
  44. //
  45. // Class TClientWindow
  46. // ~~~~~ ~~~~~~~~~~~~~
  47. class TClientWindow : public TWindow {
  48.   public:
  49.     TClientWindow(TWindow* parent= 0);
  50.    ~TClientWindow();
  51.  
  52.   protected:
  53.     void            Paint(TDC& dc, bool erase, TRect& rect);
  54.  
  55.     // Event handlers
  56.     //
  57.     void            EvSize(uint sizeType, TSize& size);
  58.  
  59.     void            CmAddHeaderItem();
  60.     void            CeAddHeaderItem(TCommandEnabler& ce)
  61.                     {ce.Enable(ColHdr && ColHdr->IsWindow());}
  62.  
  63.     void            CmRemoveHeaderItem();
  64.     void            CeRemoveHeaderItem(TCommandEnabler& ce)
  65.                     {ce.Enable(ColHdr && ColHdr->IsWindow()
  66.                                       && ColHdr->GetCount());}
  67.  
  68.     void            CmChangeHeaderFont();
  69.     void            CeChangeHeaderFont(TCommandEnabler& ce)
  70.                     {ce.Enable(ColHdr && ColHdr->IsWindow()
  71.                                       && ColHdr->GetCount());}
  72.  
  73.     void            CmResizing(){AllowResizing = !AllowResizing;}
  74.     void            CeResizing(TCommandEnabler& ce)
  75.                     {ce.SetCheck(AllowResizing ? Chk : UnChk);}
  76.  
  77.     void            CmClicking();
  78.     void            CeClicking(TCommandEnabler& ce)
  79.                     {ce.SetCheck(ColHdr->GetStyle() & HDS_BUTTONS ? Chk : UnChk);}
  80.  
  81.     // Handlers for ColumnHeader notifications
  82.     //
  83.     bool            ColHdrBeginTrack(THdrNotify far&);
  84.     void            ColHdrEndTrack(THdrNotify far&);
  85.     void            ColHdrDividerDblClick(THdrNotify far&);
  86.     void            ColHdrItemChanged(THdrNotify far&);
  87.     bool            ColHdrItemChanging(THdrNotify far& notify);
  88.     void            ColHdrItemClick(THdrNotify far&);
  89.     bool            ColHdrTrack(THdrNotify far&);
  90.  
  91.     // ColumnHeader-related Data members
  92.     //
  93.     TColumnHeader*  ColHdr;
  94.     bool            AllowResizing;
  95.     bool            AllowClicking;
  96.     TPointer<TFont> ColHdrFont;
  97.  
  98.   DECLARE_RESPONSE_TABLE(TClientWindow);
  99. };
  100.  
  101. DEFINE_RESPONSE_TABLE1(TClientWindow, TWindow)
  102.   EV_WM_SIZE,
  103.   EV_COMMAND(CM_ADDITEM,              CmAddHeaderItem),
  104.   EV_COMMAND_ENABLE(CM_ADDITEM,       CeAddHeaderItem),
  105.   EV_COMMAND(CM_REMOVEITEM,           CmRemoveHeaderItem),
  106.   EV_COMMAND_ENABLE(CM_REMOVEITEM,    CeRemoveHeaderItem),
  107.   EV_COMMAND(CM_CHANGEFONT,           CmChangeHeaderFont),
  108.   EV_COMMAND_ENABLE(CM_CHANGEFONT,    CeChangeHeaderFont),
  109.   EV_COMMAND(CM_ALLOWRESIZING,        CmResizing),
  110.   EV_COMMAND_ENABLE(CM_ALLOWRESIZING, CeResizing),
  111.   EV_COMMAND(CM_ALLOWCLICKING,        CmClicking),
  112.   EV_COMMAND_ENABLE(CM_ALLOWCLICKING, CeClicking),
  113.   EV_HDN_BEGINTRACK(ColHdrID,         ColHdrBeginTrack),
  114.   EV_HDN_DIVIDERDBLCLICK(ColHdrID,    ColHdrDividerDblClick),
  115.   EV_HDN_ENDTRACK(ColHdrID,           ColHdrEndTrack),
  116.   EV_HDN_ITEMCHANGED(ColHdrID,        ColHdrItemChanged),
  117.   EV_HDN_ITEMCHANGING(ColHdrID,       ColHdrItemChanging),
  118.   EV_HDN_ITEMCLICK(ColHdrID,          ColHdrItemClick),
  119.   EV_HDN_TRACK(ColHdrID,              ColHdrTrack),
  120. END_RESPONSE_TABLE;
  121.  
  122.  
  123. TClientWindow::TClientWindow(TWindow* parent)
  124. :
  125.   TWindow(parent),
  126.   AllowResizing(true),
  127.   AllowClicking(true)
  128. {
  129.   uint32 oldStyle = GetStyle();
  130.   SetStyle(oldStyle |= (WS_CLIPSIBLINGS|WS_CLIPCHILDREN));
  131.  
  132.   ColHdr = new TColumnHeader(this, ColHdrID, 0, 0, 0, 0);
  133.   oldStyle = ColHdr->GetStyle();
  134.   ColHdr->SetStyle(oldStyle |= HDS_BUTTONS);
  135. };
  136.  
  137. TClientWindow::~TClientWindow()
  138. {
  139.   delete ColHdr;
  140. }
  141.  
  142. //
  143. // Handles WM_SIZE message sent to client window. This method simply
  144. // invokes the 'Layout' method of the 'TColumnHeader' class.
  145. void
  146. TClientWindow::EvSize(uint sizeType, TSize& size)
  147. {
  148.   TWindow::EvSize(sizeType, size);
  149.  
  150.   // Layout header at top of window
  151.   //
  152.   if (ColHdr)
  153.     ColHdr->Layout();
  154. }
  155.  
  156. //
  157. // WM_PAINT Handler: Draws the rectangle underneath each column
  158. //                   using the color stored in the item data of
  159. //                   the column...
  160. //
  161. void
  162. TClientWindow::Paint(TDC& dc, bool /*erase*/, TRect& /*rect*/)
  163. {
  164.   TRect clientRect = GetClientRect();
  165.   int count = ColHdr->GetCount();
  166.  
  167.   if (!count) {
  168.     char* noItemMsg = "ColumnHeader contains no items.  Please add items.";
  169.     dc.DrawText(noItemMsg, -1, clientRect,
  170.                 DT_SINGLELINE|DT_CENTER|DT_VCENTER);
  171.   }
  172.   else {
  173.     TRect columnRect;
  174.     int x = clientRect.left;
  175.     for (int i=0; i<count; i++) {
  176.       THdrItem hdrItem;
  177.       ColHdr->GetItem(hdrItem, i, HDI_LPARAM|HDI_WIDTH);
  178.       columnRect.Set(x, clientRect.top, x+hdrItem.cxy, clientRect.bottom);
  179.       dc.FillRect(columnRect, TBrush(TColor(hdrItem.lParam)));
  180.       x += hdrItem.cxy;
  181.     }
  182.   }
  183. }
  184.  
  185. //
  186. // Prompts user for some text and creates a new header item
  187. //
  188. void
  189. TClientWindow::CmAddHeaderItem()
  190. {
  191.   char itemText[100] = {0};
  192.   if (TInputDialog(this, "New Item", "Enter item:",
  193.                    itemText, sizeof(itemText)).Execute() == IDOK) {
  194.  
  195.     // Add text and a random color as item
  196.     //
  197.     THdrItem hdrItem(itemText);
  198.     hdrItem.SetItemData(RGB(random(UCHAR_MAX),
  199.                             random(UCHAR_MAX),
  200.                             random(UCHAR_MAX)));
  201.     ColHdr->Add(hdrItem);
  202.     Invalidate(true);
  203.   }
  204. }
  205.  
  206. //
  207. // Removes an item from the header control
  208. //
  209. void
  210. TClientWindow::CmRemoveHeaderItem()
  211. {
  212.   char itemIndex[10] = {0};
  213.   if (ColHdr->GetCount() > 0) {
  214.     TInputDialog inputdlg(this, "Remove Item", "Enter index (zero-based):",
  215.                           itemIndex, sizeof(itemIndex), 0,
  216.                           new TRangeValidator(0, ColHdr->GetCount()-1));
  217.     if (inputdlg.Execute() == IDOK) {
  218.       int index = atoi(itemIndex);
  219.       ColHdr->Delete(index);
  220.       Invalidate(true);
  221.     }
  222.   } else {
  223.     MessageBox("No items to remove");
  224.   }
  225. }
  226.  
  227. //
  228. // Changes the font used in the header control
  229. //
  230. void
  231. TClientWindow::CmChangeHeaderFont()
  232. {
  233.   TChooseFontDialog::TData FontData;
  234.  
  235.   FontData.DC = 0;
  236.   FontData.Flags =
  237.     CF_EFFECTS | CF_FORCEFONTEXIST | CF_SCREENFONTS | CF_INITTOLOGFONTSTRUCT;
  238.   FontData.Color = 0;
  239.   FontData.Style = 0;
  240.   FontData.FontType = SCREEN_FONTTYPE;
  241.   FontData.SizeMin = 0;
  242.   FontData.SizeMax = 0;
  243.  
  244.   // Fill FontData.LogFont with info about the column header's current font
  245.   //
  246.   TPointer<TFont> oldFont;
  247.   HFONT hFont = ColHdr->GetWindowFont();
  248.   if (hFont) {
  249.     oldFont = new TFont(hFont);
  250.   }
  251.   else {
  252.     oldFont = new TFont((HFONT)::GetStockObject(SYSTEM_FONT));
  253.   }
  254.   oldFont->GetObject(FontData.LogFont);
  255.  
  256.   // Ask user to select a new font.  Send font to column header.
  257.   if (TChooseFontDialog(this, FontData).Execute() == IDOK) {
  258.     ColHdrFont = new TFont(&FontData.LogFont);
  259.     ColHdr->SetWindowFont(ColHdrFont->GetHandle(), true);
  260.   }
  261. }                                
  262.  
  263. //
  264. // Toggle the style bit that controls whether the
  265. // column header receives HDN_ITEMCLICK notifications.
  266. //
  267. void
  268. TClientWindow::CmClicking()
  269. {
  270.   uint32 oldStyle = ColHdr->GetStyle();
  271.   ColHdr->SetStyle(oldStyle ^= HDS_BUTTONS);
  272.   ColHdr->Invalidate();
  273. }
  274.  
  275. //
  276. // Handles HDN_BEGINTRACK notifications...
  277. //
  278. bool
  279. TClientWindow::ColHdrBeginTrack(THdrNotify far&)
  280. {
  281.   return AllowResizing ? false : true;
  282. }
  283.  
  284. //
  285. // Handles HDN_ENDTRACK notifications...
  286. //
  287. void
  288. TClientWindow::ColHdrEndTrack(THdrNotify far&)
  289. {
  290.   Invalidate(true);
  291. }
  292.  
  293. //
  294. // Handles HDN_DIVIDERDBLCLK notifications...
  295. //
  296. void
  297. TClientWindow::ColHdrDividerDblClick(THdrNotify far&)
  298. {
  299.   MessageBeep(0);
  300.   MessageBeep(0);
  301. }
  302.  
  303. //
  304. //
  305. //
  306. void
  307. TClientWindow::ColHdrItemChanged(THdrNotify far&)
  308. {
  309.   Invalidate(true);
  310. }
  311.  
  312. // Handle HDN_ITEMCHANGING notification
  313. // This notification comes when any attribute of a given
  314. // item is about to change.
  315. //
  316. bool
  317. TClientWindow::ColHdrItemChanging(THdrNotify far& notify)
  318. {
  319.   // Mask flags indicate what is changing.  If the user
  320.   // is re-sizing a column, the width bit is set.
  321.   //
  322.   if (notify.pitem->mask & HDI_WIDTH)  
  323.     return AllowResizing ? false : true;   
  324.  
  325.   return false;               // allow any other change
  326. }
  327.  
  328. //
  329. // Handles HDN_ITEMCLICK notifications
  330. // 
  331. //
  332. void
  333. TClientWindow::ColHdrItemClick(THdrNotify far& hdrNotify)
  334. {
  335.   // Retrieve the HeaderItem of the clicked guy
  336.   // in case we need some info...
  337.   //
  338.   THdrItem hdrItem;
  339.   ColHdr->GetItem(hdrItem, hdrNotify.iItem, HDI_LPARAM);
  340.  
  341.   // Update the LPARAM (color)....
  342.   //
  343.   hdrItem.SetItemData(RGB(random(UCHAR_MAX),
  344.                           random(UCHAR_MAX),
  345.                           random(UCHAR_MAX)));
  346.   ColHdr->SetItem(hdrItem, hdrNotify.iItem);
  347.  
  348.   // Force a redraw
  349.   //
  350.   Invalidate(false);
  351. }
  352.  
  353. //
  354. // Handles HDN_TRACK notifications...
  355. //
  356. bool
  357. TClientWindow::ColHdrTrack(THdrNotify far&)
  358. {
  359.   return AllowResizing ? false : true;
  360. }
  361.  
  362. void
  363. TSampleApp::InitMainWindow()
  364. {
  365.   SetMainWindow(new TFrameWindow(0, "ColumnHeader Example", 
  366.                 new TClientWindow()));
  367.   GetMainWindow()->AssignMenu(IDM_APPMENU);
  368. }
  369.  
  370. int
  371. OwlMain(int /*argc*/, char* /*argv*/ [])
  372. {
  373.   return TSampleApp().Run();
  374. }
  375.